播放列表中的歌单排行
本文作者:石 艳,中南财经政法大学统计与数学学院
本文编辑:张孟晗
技术总编:陈 鼎
Stata&Python云端课程来啦!
为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!!!Stata&Python特惠课程双双上线腾讯课堂~爬虫俱乐部推出了Python编程培训课程、Stata基础课程、Stata进阶课程、Stata文本分析、正则表达式、网络爬虫、基本字符串课程。报名课程即可加入答疑群,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦。我们在这篇推文的最后提供了每门课程的课程二维码,大家有需要的话可以直接扫描二维码查看课程详情并进行购买哦~
引言
1、数据获取
https://music.163.com/#/discover/playlist/order=hot&cat=%E5%9C%B0%E9%93%81&limit=35&offset=35
from bs4 import BeautifulSoup
import requests
import time
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
# 主要获取歌单详情的链接
for i in range(0, 1295, 35):
print("正在抓取第%s页"%(i/35))
time.sleep(3)
url = 'https://music.163.com/discover/playlist/?order=hot&cat=%E5%9C%B0%E9%93%81&limit=35&offset=' + str(i)
response = requests.get(url=url, headers=headers)
html = response.text
soup = BeautifulSoup(html, 'html.parser')
# 获取包含歌单详情页网址的标签
ids = soup.select('.dec a')
# 获取包含歌单索引页信息的标签
lis = soup.select('#m-pl-container li')
# print(len(lis))
for j in range(len(lis)):
# 获取歌单详情页地址
url = ids[j]['href']
# 获取歌单标题,替换英文分割符
title = ids[j]['title'].replace(',', ',')
# 获取歌单播放量
# play = lis[j].select('.nb')[0].get_text()
# 获取歌单贡献者名字
user = lis[j].select('p')[1].select('a')[0].get_text()
# 输出歌单索引页信息
# print(url, title, play, user)
# 将信息写入CSV文件中
with open(r'.\playlist.csv', 'a+', encoding='utf-8-sig') as f:
f.write(url + ',' + title + ',' + play + ',' + user + '\n')
df = pd.read_csv(r'.\playlist.csv', header=None, error_bad_lines=False, names=['url', 'title', 'play', 'user'])
for i in range(0,len(df['url'])-1):
print('正在抓取第%s个歌单信息'%(i+1))
time.sleep(3)
url = 'https://music.163.com' + df['url'][i]
response = requests.get(url=url, headers=headers)
html = response.text
soup = BeautifulSoup(html, 'html.parser')
# 获取歌单标题
title = soup.select('h2')[0].get_text().replace(',', ',')
# 获取标签
tags = []
tags_message = soup.select('.u-tag i')
for p in tags_message:
tags.append(p.get_text())
# 对标签进行格式化
if len(tags) > 1:
tag = '-'.join(tags)
else:
tag = tags[0]
# 获取歌单介绍
if soup.select('#album-desc-more'):
text = soup.select('#album-desc-more')[0].get_text().replace('\n', '').replace(',', ',')
else:
text = '无'
# 获取歌单收藏量
collection = soup.select('#content-operation i')[1].get_text().replace('(', '').replace(')', '')
# 歌单播放量
play = soup.select('.s-fc6')[0].get_text()
# 歌单内歌曲数
songs = soup.select('#playlist-track-count')[0].get_text()
# 歌单评论数
comments = soup.select('#cnt_comment_count')[0].get_text()
# 输出歌单详情页信息
# print(title, tag, text, collection, play, songs, comments)
# 将详情页信息写入CSV文件中
with open(r'.\music_message.csv', 'a+', encoding='utf-8-sig') as f:
f.write(title + ',' + tag + ',' + text + ',' + collection + ',' + play + ',' + songs + ',' + comments + '\n')
2、数据可视化
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv(r'.\playlist.csv', header=None, error_bad_lines=False, names=['url', 'title', 'play', 'user'])
# 数据聚合分组
place_message = df.groupby(['user'])
place_com = place_message['user'].agg(['count'])
place_com.reset_index(inplace=True)
place_com_last = place_com.sort_index()
dom = place_com_last.sort_values('count', ascending=False)[0:10]
# 设置显示数据
names = [i for i in dom.user]
names.reverse()
nums = [i for i in dom['count']]
nums.reverse()
data = pd.Series(nums, index=names)
# 设置图片显示属性,字体及大小
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['font.size'] = 10
plt.rcParams['axes.unicode_minus'] = False
# 设置图片显示属性
fig = plt.figure(figsize=(16, 8), dpi=80)
ax = plt.subplot(1, 1, 1)
ax.patch.set_color('white')
# 设置坐标轴属性
lines = plt.gca()
# 设置坐标轴颜色
lines.spines['right'].set_color('none')
lines.spines['top'].set_color('none')
lines.spines['left'].set_color((64/255, 64/255, 64/255))
lines.spines['bottom'].set_color((64/255, 64/255, 64/255))
# 设置坐标轴刻度
lines.xaxis.set_ticks_position('none')
lines.yaxis.set_ticks_position('none')
# 绘制柱状图,设置柱状图颜色
data.plot.barh(ax=ax, width=0.7, alpha=0.7, color=(153/255, 0/255, 102/255))
# 添加标题,设置字体大小
ax.set_title('歌单贡献UP主 TOP10', fontsize=18, fontweight='light')
# 添加歌曲出现次数文本
for x, y in enumerate(data.values):
plt.text(y+0.3, x-0.12, '%s' % y, ha='center')
# 显示图片
plt.show()
import re
df1 = pd.read_csv(r'.\music_message.csv', header=None, error_bad_lines=False, names=['title', 'tag', 'introduce', 'collection', 'play', 'count','comment'])
df1['collection']=df1['collection'].apply(lambda x: str(x).replace('收藏','0'))
df1['collection'] = df1['collection'].apply(lambda x: float(re.sub('万','',str(x)))*10000 if str(x).find('万')!=-1 else float(x))
df1['play']=df1['play'].apply(lambda x: float(x))
df1['count']=df1['count'].apply(lambda x: float(x))
df1['comment']=df1['comment'].replace('评论',int(0))
df1['comment']=df1['comment'].apply(lambda x: float(x))
names=df1.sort_values(by='play',axis=0,ascending=False)['title'][:10]
plays = df1.sort_values(by='play', axis=0,ascending=False)['play'][:10]
# 设置显示数据
names = [i for i in names]
names.reverse()
plays = [i for i in plays]
plays.reverse()
data = pd.Series(plays, index=names)
names=df1.sort_values(by='collection',axis=0,ascending=False)['title'][:10]
collection = df1.sort_values(by='collection', axis=0,ascending=False)['collection'][:10]
# 设置显示数据
names = [i for i in names]
names.reverse()
collection = [i for i in collection]
collection.reverse()
data = pd.Series(collection, index=names)
2.4“地铁”场景歌单评论TOP10
names=df1.sort_values(by='comment',axis=0,ascending=False)['title'][:10]
comment = df1.sort_values(by='comment', axis=0,ascending=False)['comment'][:10]
# 设置显示数据
names = [i for i in names]
names.reverse()
comment = [i for i in comment]
comment.reverse()
data = pd.Series(comment, index=names)
2.5“地铁”场景歌单标签分布
# 处理标签信息
tags = []
dom2 = []
for i in df1['tag']:
c = i.split('-')
for j in c:
if j not in tags:
tags.append(j)
else:
continue
# len(tags)
for item in tags:
num = 0
for i in df1['tag']:
type2 = i.split('-')
for j in range(len(type2)):
if type2[j] == item:
num += 1
else:
continue
dom2.append(num)
# len(dom2)
# 数据创建
data = {'tags': tags, 'num': dom2}
frame = pd.DataFrame(data)
df2 = frame.sort_values(by='num', ascending=False)
name = df2['tags'][:10]
income = df2['num'][:10]
# 绘图details
colors = ['#993333', '#CC9966', '#333333', '#663366', '#003366', '#009966', '#FF6600', '#FF0033', '#009999', '#333366']
plot = squarify.plot(sizes=income, label=name, color=colors, alpha=1, value=income, edgecolor='white', linewidth=1.5)
# 设置图片显示属性,字体及大小
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['font.size'] = 20
plt.rcParams['axes.unicode_minus'] = False
# 设置标签大小为1
plt.rc('font', size=6)
# 设置标题大小
plot.set_title('地铁情景歌单标签图', fontsize=20, fontweight='light')
# 除坐标轴
plt.axis('off')
# 除上边框和右边框刻度
plt.tick_params(top=False, right=False)
# 图形展示
plt.show()
今天的内容分享就到这儿了,希望大家能够找到自己喜欢的歌单,让无聊的场景变得稍微有趣一点~
腾讯课堂课程二维码
对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!
往期推文推荐
在Stata中轻松运用program编写命令
Meta Analysis in Stata17芒果TV视频弹幕爬取之《我在他乡挺好的》
Stata中的判断神器——confirm命令
cngdf——名义GDP与实际GDP之间的摆渡船最近《扫黑风暴》有点火爆!我从豆瓣评论中发现了这些……
随机森林-Random Forest
复原之神--preserve&restore
合并,“纵”享新丝滑:frameappend & xframeappend什么是全局配置项?|从零开始的Pyecharts(二)帮你拿下数据可视化|从零开始的Pyecharts
Stata助力疫情打卡管理——是谁没有接龙呢?
这十年,《金融研究》的编委和读者偏爱哪些研究话题和文章?【案例展示】Python与数据库交互
学好这一手,英语词典常在手玩转Stata中的数学函数
用spmap看中国空气质量戳穿围城面具:安利&劝退一个专业
走进图文并茂的攻略世界
玩转word文档“大变身”——wordconvert
简述递归
OpenCV库——轻松更换证件照背景色800万年薪!还有谁?!
千古伤心词人,词伤几何?
去哪儿网攻略爬取——跟我一起去大理吧
"有你才有团"——Stata爬取王者荣耀英雄海报
如何获取衡量股民情绪的指标?|东方财富股吧标题爬虫
利用Python构建马科维茨有效边界
rangestat,让统计量灵活滚动起来!
关于我们
微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。
武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。
此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。
投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。